Skip to content

feat(telegram): add inline keyboard to /session_recent, accept plain_dir in topic adoption - #3904

Closed
gimso2x wants to merge 2 commits into
Yeachan-Heo:devfrom
gimso2x:feat/session-recent-keyboard
Closed

feat(telegram): add inline keyboard to /session_recent, accept plain_dir in topic adoption#3904
gimso2x wants to merge 2 commits into
Yeachan-Heo:devfrom
gimso2x:feat/session-recent-keyboard

Conversation

@gimso2x

@gimso2x gimso2x commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

What

  • /session_recent: inline keyboard buttons with switch_inline_query_current_chat — tap a session button to insert /session_resume <id> into chat input, no callback polling needed
  • Topic adoption direct path input: existing_pathplain_dir so missing directories are auto-created by the lifecycle orchestrator
  • Simplified double .map() over recent.entries into single for-loop pass

Why

  • Users wanted session selection buttons in Telegram instead of plain text list
  • Users typing folder paths like ~/docs got "folder no longer available" when the directory didn't exist — now it is created automatically

Testing

  • bun test notifications-telegram-daemon.test.ts notifications-lifecycle-command-routing.test.ts514 pass, 0 fail
  • Updated lifecycle-command-routing test to verify inline keyboard format
  • Updated daemon test to verify plain_dir target

GJC verdict

gajae.pr-review-verdict.v1 needs-human sha256:39b9f86f199c2ac4a4547753ff2b81d014162303 reviewer:human evidence:bun test (514 pass)

@gimso2x
gimso2x force-pushed the feat/session-recent-keyboard branch from aa33a4b to 08e1222 Compare August 5, 2026 23:11

@yazzang-homelab yazzang-homelab left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed as independent architect review. CI is green and the head contains current dev, but there are three things to fix before this should land.

1. Blocking — /session_recent silently lost disable_notification.

The old replyHtml helper carried telegramDisableNotification(this.opts.sound, "finalized"). The new inline sendMessage loop does not:

await this.botApi.call("sendMessage", {
  chat_id: this.opts.chatId,
  ...(threadId !== undefined ? { message_thread_id: threadId } : {}),
  text: chunks[i]!,
  parse_mode: TELEGRAM_PARSE_MODE,
  ...(i === chunks.length - 1 ? { reply_markup: { inline_keyboard } } : {}),
});

So a user who configured silent finalized notifications now gets a push for every /session_recent. The sibling reply helper right above still honours it, which makes the inconsistency easy to miss in review. Restore the flag (or keep replyHtml and give it an optional reply_markup parameter — that also removes the duplicated chunk loop).

2. Blocking — CHANGELOG.

This is user-visible twice over (new inline keyboard on /session_recent, and topic adoption now accepts a non-existent directory). packages/coding-agent/CHANGELOG.md is untouched; the PR checklist item is unticked.

3. Please split — the plain_dir change is a policy change wearing a UI change's PR.

existing_pathplain_dir in topic adoption means a Telegram message now causes fs.mkdirSync(cwd, { recursive: true }) in lifecycle-control-runtime.ts. The test being flipped was an explicit assertion (pending topics reject dir and worktree creates instead of spawning duplicate topics), so this is deliberately reversing a prior decision — that deserves its own PR with its own reasoning, not a bullet under a keyboard feature. Concretely, please state in that PR: what bounds the created path (the chat is full-trust, but normalizeLifecyclePath accepts any absolute path, so /session_create path /etc/whatever now creates a directory), and what happens to the directory if session creation subsequently fails — is it left behind?

Non-blocking notes:

  • e.sessionId.slice(0, 12) in the button payload is fine — validateLifecycleTarget routes resume through sessionIdOrPrefix — but the test fixtures use 5-char ids (s-019), so truncation is never actually exercised. Worth one case with a full-length session id.
  • Telegram caps inline_keyboard rows in practice; recent.entries is unbounded here. Cap the button list (the text list can stay long since it already chunks).
  • Only the last chunk carries reply_markup, which is correct, but the chunk loop no longer awaits ordering failures — a rejected middle chunk is swallowed by .catch(() => undefined) and the keyboard still posts. Pre-existing pattern, just noting it now applies to a multi-message body.
gajae.pr-review-verdict.v1 merge-blocked sha256:c19e8ecf2e895399636e22399923c4f12841773f reviewer:architect evidence:https://github.com/Yeachan-Heo/gajae-code/pull/3904/files

gimso2x added 2 commits August 6, 2026 20:26
…dir in topic adoption

- /session_recent: inline keyboard with switch_inline_query_current_chat buttons
  inserts /session_resume <id> into chat input, no callback polling needed
- topic adoption direct path input: plain_dir instead of existing_path
  missing directories are created by the lifecycle orchestrator
- combined double .map() over recent.entries into single for-loop pass

Rejected: multibyte-safe title slice | cosmetic, Telegram enforces 1-256 char limit
Confidence: high
Scope-risk: narrow
Reversibility: clean
Tested: bun test (558 pass, 0 fail)
Not-tested: runtime end-to-end Telegram API integration
- /session_recent rewrite left replyHtml unused; biome check failed
- TelegramAdoptionTarget and persisted-intent guard now accept plain_dir
  so topic-adoption direct paths survive daemon restart
@Yeachan-Heo
Yeachan-Heo force-pushed the feat/session-recent-keyboard branch from c19e8ec to 4236fb7 Compare August 6, 2026 11:26
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Closing during the emergency maintenance freeze. This PR is not in the retained critical or maintainer-owned set. Do not open a replacement PR unless a maintainer explicitly directs it.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo Yeachan-Heo closed this Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants